﻿using Onshi.POS.Modelo.Entidades;
using Onshi.POS.Modelo.Enumeradores;
using Onshi.POS.Repositorios;
using Onshi.POS.Comun.Vistas;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Onshi.POS.Comun
{
    public class ImpuestosPresentador
    {
        #region Constructores

        public ImpuestosPresentador(IImpuestos vista)
        {
            this.vista = vista;
        }

        #endregion

        #region Atributos

        private IImpuestos vista;
        private List<Impuesto> listado;

        #endregion

        #region Propiedades

        private RepositorioEventos RepositorioEventos
        {
            get { return new RepositorioEventos(); }
        }

        private RepositorioTiposImpuestos RepositorioTiposImpuestos
        {
            get { return new RepositorioTiposImpuestos(); }
        }

        private RepositorioImpuestos RepositorioImpuestos
        {
            get { return new RepositorioImpuestos(); }
        }

        private RepositorioUsuarios RepositorioUsuarios
        {
            get { return new RepositorioUsuarios(); }
        }

        private RepositorioRegistros RepositorioRegistros
        {
            get { return new RepositorioRegistros(); }
        }

        private RepositorioPermisos RepositorioPermisos
        {
            get { return new RepositorioPermisos(); }
        }

        #endregion

        #region Metodos

        private void CargarFiltrarLista()
        {
            listado = RepositorioImpuestos.DevolverTodos();
            Filtrar();
        }

        public void Inicializar()
        {
            listado = RepositorioImpuestos.DevolverTodos();
            vista.ListadoImpuestos = listado.Where(x => !x.EstaEliminado).ToList();
        }

        public void Eliminar()
        {
            var usuarioSistema = RepositorioUsuarios.DevolverPorId(vista.IdUsuarioSistema);
            if (usuarioSistema == null)
                throw new Exception("El usuario no existe");
            if (!usuarioSistema.Perfil.Permisos.Exists(x => x.Id == (Byte)EnumPermisos.ImpuestosBaja))
                throw new Exception("Permisos insuficientes");

            var impuesto = RepositorioImpuestos.DevolverPorId(vista.IdImpuesto);
            if (impuesto == null)
                throw new Exception("El impuesto no existe");
            if (impuesto.EstaEliminado)
                throw new Exception("El impuesto ya se encuentra eliminado");

            var registro = new Registro();
            registro.Usuario = usuarioSistema;
            registro.Evento = RepositorioEventos.DevolverPorId((Byte)EnumEventos.ImpuestosBaja);
            if (registro.Evento == null)
                throw new Exception("El evento no existe");

            impuesto.EstaEliminado = true;
            RepositorioImpuestos.Modificar(impuesto);
            RepositorioRegistros.Insertar(registro, impuesto);

            CargarFiltrarLista();
        }

        public void Actualizar()
        {
            CargarFiltrarLista();
        }

        public void Filtrar()
        {
            var consulta = (from item in listado
                            where item.Nombre.Trim().ToLower().Contains(vista.NombreFiltro.Trim().ToLower())
                            & item.TieneObservaciones == (vista.ObservacionesFiltro == EnumSiNo.Todos ? item.TieneObservaciones : (vista.ObservacionesFiltro == EnumSiNo.Si ? true : false))
                            & item.EstaEliminado == (vista.EstadoFiltro == EnumActivoInactivo.Todos ? item.EstaEliminado : (vista.EstadoFiltro == EnumActivoInactivo.Inactivo ? true : false))
                            & item.Tipo.Id == (vista.IdTipoImpuestoFiltro == (Byte)EnumTiposImpuestos.Todos ? item.Tipo.Id : vista.IdTipoImpuestoFiltro)
                            & (item.Valor >= vista.ValorDesdeFiltro & item.Valor <= vista.ValorHastaFiltro)
                            & (item.MontoMaximo >= vista.MontoMaximoDesdeFiltro & item.MontoMaximo <= vista.MontoMaximoHastaFiltro)
                            & (item.MontoAplicable >= vista.MontoAplicableDesdeFiltro & item.MontoAplicable <= vista.MontoAplicableHastaFiltro)
                            select item).ToList();
            vista.ListadoImpuestos = consulta;
        }

        public void Habilitar()
        {
            var usuarioSistema = RepositorioUsuarios.DevolverPorId(vista.IdUsuarioSistema);
            if (usuarioSistema == null)
                throw new Exception("El usuario no existe");
            if (!usuarioSistema.Perfil.Permisos.Exists(x => x.Id == (Byte)EnumPermisos.ImpuestosHabilitacion))
                throw new Exception("Permisos insuficientes");

            var impuesto = RepositorioImpuestos.DevolverPorId(vista.IdImpuesto);
            if (impuesto == null)
                throw new Exception("El impuesto no existe");
            if (!impuesto.EstaEliminado)
                throw new Exception("El impuesto ya se encuentra habilitado");

            var registro = new Registro();
            registro.Usuario = usuarioSistema;
            registro.Evento = RepositorioEventos.DevolverPorId((Byte)EnumEventos.ImpuestosHabilitacion);
            if (registro.Evento == null)
                throw new Exception("El evento no existe");

            impuesto.EstaEliminado = false;
            RepositorioImpuestos.Modificar(impuesto);
            RepositorioRegistros.Insertar(registro, impuesto);

            CargarFiltrarLista();
        }

        public void Aceptar()
        {
            var usuario = RepositorioUsuarios.DevolverPorId(vista.IdUsuarioSistema);
            if (usuario == null)
                throw new Exception("El usuario no existe");
            if (vista.IdImpuesto == 0)
            {
                if (!usuario.Perfil.Permisos.Exists(x => x.Id == (Byte)EnumPermisos.ImpuestosAlta))
                    throw new Exception("Permisos insuficientes");
            }
            else if (!usuario.Perfil.Permisos.Exists(x => x.Id == (Byte)EnumPermisos.ImpuestosModificacion))
                throw new Exception("Permisos insuficientes");

            if (String.IsNullOrWhiteSpace(vista.Nombre))
                throw new Exception("El nombre no puede quedar vacío");
            if (vista.Valor < 0)
                throw new Exception("El valor no puede ser menor a cero");
            if (vista.MontoMaximo < 0)
                throw new Exception("El monto maximo no puede ser menor a cero");
            if (vista.MontoAplicable < 0)
                throw new Exception("El monto aplicable no puede ser menor a cero");

            Impuesto impuesto;
            if (vista.IdImpuesto != 0)
            {
                impuesto = RepositorioImpuestos.DevolverPorId(vista.IdImpuesto);
                if (impuesto == null)
                    throw new Exception("El impuesto no existe");
            }
            else
                impuesto = new Impuesto();

            impuesto.Tipo = RepositorioTiposImpuestos.DevolverPorId(vista.IdTipoImpuesto);
            if (impuesto.Tipo == null)
                throw new Exception("El tipo de impuesto no existe");
            impuesto.Nombre = vista.Nombre.Trim();
            impuesto.Observaciones = vista.Observaciones.Trim();
            impuesto.Valor = vista.Valor;
            impuesto.MontoAplicable = vista.MontoAplicable;
            impuesto.MontoMaximo = vista.MontoMaximo;

            var registro = new Registro();
            registro.Usuario = usuario;
            if (vista.IdImpuesto == 0)
                registro.Evento = RepositorioEventos.DevolverPorId((Byte)EnumEventos.ImpuestosAlta);
            else
                registro.Evento = RepositorioEventos.DevolverPorId((Byte)EnumEventos.ImpuestosModificacion);
            if (registro.Evento == null)
                throw new Exception("El evento no existe");

            if (vista.IdImpuesto == 0)
                RepositorioImpuestos.Insertar(impuesto);
            else
                RepositorioImpuestos.Modificar(impuesto);
            RepositorioRegistros.Insertar(registro);

            CargarFiltrarLista();
        }

        #endregion
    }
}
